import jwt
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.http.response import JsonResponse
from django.utils.deprecation import MiddlewareMixin
from rest_framework.authentication import get_authorization_header
from rest_framework.status import HTTP_403_FORBIDDEN
from django.shortcuts import reverse
from apps.oaauth.models import OAUser


class LogincheckMiddleware(MiddlewareMixin):
    keyword = 'JWT'
    model = None

    def process_view(self, request, view_func, view_args, view_kwargs):
        # 白名单路径,不需要验证token
        white_list = [reverse("oaauth:login"), reverse("staff:active_staff")]
        if request.path in white_list or request.path.startswith(settings.MEDIA_URL):
            request.user = AnonymousUser()
            request.auth = None
            return None

        try:
            auth = get_authorization_header(request).split()
            if not auth or auth[0].lower() != self.keyword.lower().encode():
                return JsonResponse({"detail": "请提供JWT Token"}, status=HTTP_403_FORBIDDEN)

            if len(auth) == 1:
                return JsonResponse({"detail": "没有提供Token"}, status=HTTP_403_FORBIDDEN)
            elif len(auth) > 2:
                return JsonResponse({"detail": "无效的Token格式"}, status=HTTP_403_FORBIDDEN)

            # 解密token
            jwt_token = auth[1]
            try:
                payload = jwt.decode(jwt_token, key=settings.SECRET_KEY, algorithms="HS256")
                userid = payload.get('userid')
                user = OAUser.objects.get(uid=userid)
                request.user = user
                request.auth = jwt_token
                return None
            except jwt.ExpiredSignatureError:
                return JsonResponse({"detail": "Token已过期"}, status=HTTP_403_FORBIDDEN)
            except (OAUser.DoesNotExist, Exception):
                return JsonResponse({"detail": "用户不存在或Token无效"}, status=HTTP_403_FORBIDDEN)

        except Exception as e:
            print(f"Token验证发生错误: {str(e)}")
            return JsonResponse({"detail": "Token验证失败"}, status=HTTP_403_FORBIDDEN)
